import { installer, RCRTCCode } from '@rongcloud/plugin-rtc'

export default {
  methods: {
    // 初始化 RCRTCClient，初始化过程推荐放在建立连接之前
    rtcInit() {
      this.rtcClient = this.im.install(installer);
    },

    // 加入普通音视频房间，从 5.0.7 开始增加返回 `tracks` 与 `userIds`
    async joinRoom() {
      // * userIds - 当前已加入房间的远端人员列表
      // * tracks  - 当前已发布至房间内的远端资源列表
      const { code, room, userIds, tracks: remoteTracks } = await this.rtcClient.joinRTCRoom(this.form.roomId)

      // 若加入失败，则 room、userIds、tracks 值为 undefined
      if (code !== RCRTCCode.SUCCESS) {
        console.log('加入房间失败,错误代码:', code)
        return Promise.resolve(code)
      }

      this.room = room;
      this.userIds = userIds;
      console.log(this.room, 'this.room');
      this.remoteTracks = remoteTracks;
      return Promise.resolve(null); // 成功


      // this.publishScreenShare();

    },
    // 注册房间事件监听器，重复注册时，仅最后一次注册有效
    roomWatch() {
      this.room.registerRoomEventListener({
        /**
         * 本端被踢出房间时触发
         * @description 被踢出房间可能是由于服务端超出一定时间未能收到 rtcPing 消息，所以认为己方离线。
         * 另一种可能是己方 rtcPing 失败次数超出上限，故而主动断线
         * @param byServer
         * 当值为 false 时，说明本端 rtcPing 超时
         * 当值为 true 时，说明本端收到被踢出房间通知
         */
        onKickOff(byServer) {
          if (byServer) {
            console.log('被踢出房间');
          } else {
            console.log('房间连接超时');
          }
        },
        /**
         * 接收到房间信令时回调，用户可通过房间实例的 `sendMessage(name, content)` 接口发送信令
         * @param name 信令名 string
         * @param content 信令内容 any
         * @param senderUserId 发送者 Id string
         * @param messageUId 消息唯一标识 string
         */
        onMessageReceive(name, content, senderUserId, messageUId) {
        },
        /**
         * 监听房间属性变更通知
         * @param name string
         * @param content string
         */
        onRoomAttributeChange(name, content) {
          console.log(name, content, '监听房间属性变更通知');
        },
        /**
         * 发布者禁用/启用音频
         * @param audioTrack RCRemoteAudioTrack 类实例
         */
        onAudioMuteChange(audioTrack) {
          console.log(audioTrack, '发布者禁用/启用音频');
        },
        /**
         * 发布者禁用/启用视频
         * @param videoTrack RCRemoteVideoTrack 类实例对象
         */
        onVideoMuteChange(videoTrack) {
          console.log(videoTrack, '发布者禁用/启用视频');
        },
        /**
         * 房间内其他用户新发布资源时触发
         * 如需获取加入房间之前房间内某个用户发布的资源列表，可使用 room.getRemoteTracksByUserId('userId') 获取
         * @param tracks 新发布的音轨与视轨数据列表，包含新发布的 RCRemoteAudioTrack 与 RCRemoteVideoTrack 实例
         */
         onTrackPublish: async (tracks) => {
          // 按业务需求选择需要订阅资源，通过 room.subscribe 接口进行订阅
          console.log(tracks, 'tracks');
          if (!tracks?.length) return;
          const { code } = await this.room.subscribe(tracks)
          if (code !== RCRTCCode.SUCCESS) {
            console.log('资源订阅失败 ->', code)
          }
          console.log('资源订阅', code);
        },
        /**
         * 房间用户取消发布资源
         * @param tracks 被取消发布的音轨与视轨数据列表
         * @description 当资源被取消发布时，SDK 内部会取消对相关资源的订阅，业务层仅需处理 UI 业务
         */
        onTrackUnpublish: ([{_id:id}]) => {
          this.subscriptionTracks.forEach(({_id},index) => {

            console.log(id,_id);
            if(id === _id)
            this.subscriptionTracks.splice(index,1);
          })

          console.log('房间用户取消发布资源', id);
        },
        /**
         * 订阅的音视频流通道已建立, track 已可以进行播放
         * @param track RCRemoteTrack 类实例
         */
        onTrackReady: async (track) => {
          console.log(track, '订阅的音视频流通道已建立,track 已可以进行播放');
          // this.isSubscriptionTrack = true;
          await this.$nextTick();
          console.log(track, '已可以进行播放');
          if (track.isAudioTrack()) {
            // 音轨不需要传递播放控件
            track.play()
          } else {

            // 视轨需要一个 video 标签才可进行播放
            // const element = document.createElement('video')
            // element.id = 'rc-video-' + track.getTrackId()
            // element.muted = true;
            // document.body.appendChild(element)
            // track.play(element)
            this.subscriptionTracks.push(track);
            await this.$nextTick();

            track.play(this.$refs['rc-video-' + track.getTrackId()][0])
          }
        },
        /**
         * 人员加入
         * @param userIds 加入的人员 id 列表
         */
        onUserJoin: ([userIds]) => {
          console.log('人员加入', userIds);
          this.userIds.push(userIds)
        },
        /**
         * 人员退出
         * @param userIds
         */
        onUserLeave: ([userIds]) => {
          console.log('人员退出', userIds);
          this.userIds.splice(this.userIds.indexOf(userIds),1)

        }
      })

      /**
       * 添加音量变化通知
       * @param handler 音量变化通知执行事件
       * @param gap 时间间隔，有效值为 300ms-1000ms，默认为 1000ms
       */
      this.room.onAudioLevelChange((audioLevelReportList) => {
        /* audioLevelReportList : { track: RCLocalAudioTrack | RCRemoteAudioTrack, audioLevel: number }[] */
        // console.log('添加音量变化通知', audioLevelReportList);

      }, 1000)
      console.log(' 监听完成');
    },
    // 订阅 加入房间后，房间内可能已经存在其他参会者发布的音视轨数据
    async subscribe() {
      if (!this.remoteTracks.length) return;
      const { code } = await this.room.subscribe(this.remoteTracks)

      if (code !== RCRTCCode.SUCCESS) {
        console.log(`资源订阅失败 -> code: ${code}`)
      }
      console.log('订阅成功');
    },
    // 发布屏幕共享资源
    async publishScreenShare() {
      if (!this.rtcClient || !this.room) {
        console.log('请确保已经初始化完 RTC，并已加入房间');
        return;
      }

      // 获取屏幕共享资源
      const { code, track } = await this.rtcClient.createScreenVideoTrack();
      if (code !== RCRTCCode.SUCCESS) {
        console.log(`获取资源失败: ${code}`);
        return this.$message.error(`获取资源失败: ${code}`);
      }

      // 发布
      const pubRes = await this.publishScreen([track]);
      if (pubRes !== RCRTCCode.SUCCESS) {
        console.log(`发布资源失败: ${code}`);
        return;
      }
      console.log('发布', track);
      this.publishScreenTrack = track;
      track._msTrack.onended = () => {
        this.unPublish('publishScreenTrack',this.publishScreenTrack)
        console.log('本地推流停止');
      }
    },
    // 发布
    async publishScreen(localTracks) {
      if (!localTracks.length) {
        return;
      }
      const { code } = await this.room.publish(localTracks);

      if (code === RCRTCCode.SUCCESS) {
        /**
         * 播放资源
         */
        this.localTracks = localTracks;
        // this.appendVideoEl(localTracks);

        console.log(localTracks, 'localTracks本地资源');
        await this.$nextTick();

        localTracks.forEach((track) => {
          this.playTrack(track, false);
        });

        return Promise.resolve(code);
      } else {
        console.log(`发布资源失败: ${code}`);
      }
    },
    /**
     * 播放资源
     * @param {window.RCRTC.RCTrack} track 音轨、视轨
     * @param {boolean} playAudio 是否播放音频，(本端发布的音频静音，值为 false)
     * @returns 
     */
    async playTrack(track, playAudio) {
      // 播放视频
      if (track.isVideoTrack()) {
        track.play(this.$refs['rc-video-' + track.getTrackId()][0]);
        return;
      }
      // 播放音频
      if (playAudio) {
        track.play();
      }
    },
    // 发布麦克风
    async publishMicrophoneAudio() {
      // 仅当 `code === RCRTCCode.SUCCESS` 时 audioTrack 有值
      // audioTrack 为 RCMicphoneAudioTrack 类型实例
      const { code, track } = await this.rtcClient.createMicrophoneAudioTrack()
      if (code !== RCRTCCode.SUCCESS) return this.$message.error(`获取麦克风失败: ${code}`)

      this.publishAudioOrVideo('publishMicrophoneAudioTrack',track);

    },
    // 发布摄像头
    async publishCameraVideo() {
      // 仅当 `code === RCRTCCode.SUCCESS` 时 videoTrack 有值
      // videoTrack 为 RCCameraVideoTrack 类型实例
      // const { code, track } = await this.rtcClient.createCameraVideoTrack();
      this.rtcClient.createCameraVideoTrack().then(({ code, track }) => {
        console.log(code,RCRTCCode.SUCCESS,track)
        if (code !== RCRTCCode.SUCCESS) return this.$message.error(`获取摄像头失败: ${code}`)
  
        this.publishAudioOrVideo('publishCameraVideoTrack',track);
      })

    },
    // 发布用户资源,摄像头或麦克风
    async publishAudioOrVideo(proptype,track) {

      const { code } = await this.room.publish([track])

      // 若资源发布失败
      if (code !== RCRTCCode.SUCCESS) return this.$message.error(`资源发布失败: ${code}`);

      this[proptype] = track;

    },
    // 停止发布本地资源
    async unPublish(proptype,track) { 
      const { code } = await this.room.unpublish([track])

      if (code !== RCRTCCode.SUCCESS) {
        console.log('取消发布失败:', code)
      }
      track.destroy();
      this[proptype] = null;

      if(proptype === 'publishScreenTrack'){
        this.localTracks = [];
      }
    }
  }
}